#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vector>
#include <sstream>
#include <string>

#include "actions.hpp"

struct s_action ft_actions[] =
{
  {FT_REQ_INVALID, &invalid_request},
  {FT_REQ_FILE_ADD, &add_file},
  {FT_REQ_REP_ADD, &add_directory},
  {FT_REQ_FILE_CTN, &set_file_ctn},
  {FT_REQ_FILE_REQ, &send_file_ctn},
  {FT_REQ_FILE_RM, &rm_file},
  {FT_REQ_CLEAN, &rm_directory}
};

int ft_nb_actions = sizeof(ft_actions) / sizeof(struct s_action);

typedef	std::vector<std::string>	args;

args*				getArgs(char* buf)
{
  std::istringstream		iss(buf);
  args*				arg = new std::vector<std::string>();

  do
    {
      std::string sub;
      iss >> sub;
      arg->push_back(sub);
    }
    while (iss);
  return arg;
}


void
invalid_request(struct s_ft_request *ack, void *data, const std::string& storage)
{
  if (DEBUG_MODE)
    std::cout << "This is an invalid request" << std::endl;

  (void)data;
  ack->type = FT_REQ_NACK;
  ack->data_sz = 0;
}

void
add_file(struct s_ft_request *ack, void *data, const std::string& storage)
{
  int		fd;
  args*		arg = getArgs((char*)data);

  (*arg)[1] = storage + (*arg)[1];
  if (DEBUG_MODE)
    std::cout << "adding file: " << (*arg)[1] << std::endl;

  ack->type = FT_REQ_ACK;
  ack->data_sz = 0;
  if ((fd = open((*arg)[1].c_str(), O_CREAT, 0744)) != -1)
    close(fd);
  else
    std::cout << "Failed to create: " << (*arg)[1] << std::endl;
}

void
add_directory(struct s_ft_request *ack, void *data, const std::string& storage)
{
  int		fd;
  args*		arg = getArgs((char*)data);

  (*arg)[1] = storage + (*arg)[1];
  if (DEBUG_MODE)
    std::cout << "adding directory: " << (*arg)[1] << std::endl;

  ack->type = FT_REQ_ACK;
  ack->data_sz = 0;

  if ((fd = mkdir((*arg)[1].c_str(), 0744)) != -1)
    close(fd);
  else
    std::cout << "Failed to add dir: " << (*arg)[1] << std::endl;
}

void
set_file_ctn(struct s_ft_request *ack, void *data, const std::string& storage)
{
  if (DEBUG_MODE)
    std::cout << "editing file: " << (char *)data << std::endl;

  ack->type = FT_REQ_ACK;
  ack->data_sz = 0;

}

void
send_file_ctn(struct s_ft_request *ack, void *data, const std::string& storage)
{
  if (DEBUG_MODE)
    std::cout << "sending file: " << (char *)data << std::endl;

  ack->type = FT_REQ_FILE_CTN;
  ack->data_sz = 0;
}

void
rm_file(struct s_ft_request *ack, void *data, const std::string& storage)
{
  if (DEBUG_MODE)
    std::cout << "removing file: " << (char *)data << std::endl;

  ack->type = FT_REQ_ACK;
  ack->data_sz = 0;
}

void
rm_directory(struct s_ft_request *ack, void *data, const std::string& storage)
{
  if (DEBUG_MODE)
    std::cout << "cleaning repository" << std::endl;

  (void)data;
  ack->type = FT_REQ_CLEAN;
  ack->data_sz = 0;
}
